from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.http import JsonResponse
from django.db.models import Q, Avg, Count
from django.contrib.auth import login, logout, authenticate
from django.core.paginator import Paginator
from .models import Movie, Rating, Genre
from .forms import RatingForm, MovieSearchForm, SignUpForm
from collections import Counter
from django.contrib.auth.forms import AuthenticationForm
from .services.ai_recommendation import AIRecommendationService
from .services.ai_chatbot import MovieChatbotService
from django.conf import settings

# 初始化AI服务实例
ai_recommender = AIRecommendationService()
chatbot_service = MovieChatbotService()

def movie_list(request):
    form = MovieSearchForm(request.GET)
    movies = Movie.objects.all().annotate(avg_rating=Avg('rating__rating'))
    
    if form.is_valid() and form.cleaned_data.get('query'):
        query = form.cleaned_data.get('query')
        movies = movies.filter(
            Q(title__icontains=query) | 
            Q(description__icontains=query) |
            Q(genres__name__icontains=query)
        ).distinct()
    
    selected_genre = request.GET.get('genre')
    if selected_genre:
        movies = movies.filter(genres__name=selected_genre)
    
    sort_by = request.GET.get('sort', 'title')
    if sort_by == 'rating':
        movies = movies.order_by('-avg_rating')
    elif sort_by == 'year':
        movies = movies.order_by('-year')
    else:
        movies = movies.order_by('title')
    
    genres = Genre.objects.all()
    
    context = {
        'movies': movies,
        'genres': genres,
        'form': form,
        'selected_genre': selected_genre,
        'sort_by': sort_by
    }
    return render(request, 'movies/list.html', context)

def movie_detail(request, movie_id):
    movie = get_object_or_404(Movie, id=movie_id)
    user_rating = None
    if request.user.is_authenticated:
        user_rating = Rating.objects.filter(user=request.user, movie=movie).first()
    
    form = RatingForm(instance=user_rating)
    
    if request.method == 'POST' and request.user.is_authenticated:
        form = RatingForm(request.POST, instance=user_rating)
        if form.is_valid():
            rating = form.save(commit=False)
            rating.user = request.user
            rating.movie = movie
            rating.save()
            return redirect('movie_detail', movie_id=movie.id)
    
    similar_movies = movie.recommend_similar_movies()
    
    context = {
        'movie': movie,
        'form': form,
        'user_rating': user_rating,
        'similar_movies': similar_movies,
    }
    return render(request, 'movies/detail.html', context)

@login_required
def rate_movie(request, movie_id):
    movie = get_object_or_404(Movie, id=movie_id)
    
    if request.method == 'POST':
        rating_value = request.POST.get('rating')
        comment = request.POST.get('comment', '')
        
        if rating_value:
            rating, created = Rating.objects.update_or_create(
                user=request.user,
                movie=movie,
                defaults={'rating': rating_value, 'comment': comment}
            )
            
            return JsonResponse({
                'status': 'success',
                'message': '评分已保存',
                'new_average': movie.average_rating()
            })
    
    return JsonResponse({'status': 'error', 'message': '评分失败'})

def register(request):
    print("注册视图被调用")  # 调试信息
    
    if request.method == 'POST':
        print("收到POST请求")  # 调试信息
        print(f"表单数据: {request.POST}")  # 打印表单数据（小心敏感信息）
        
        form = SignUpForm(request.POST)
        if form.is_valid():
            print("表单验证通过")  # 调试信息
            try:
                user = form.save()
                login(request, user)
                messages.success(request, "注册成功！欢迎加入电影推荐系统。")
                print(f"用户 {user.username} 注册成功")  # 调试信息
                return redirect('home')
            except Exception as e:
                print(f"注册失败: {e}")  # 调试信息
                messages.error(request, f"注册失败: {str(e)}")
        else:
            print(f"表单验证失败: {form.errors}")  # 调试信息
            for field, errors in form.errors.items():
                for error in errors:
                    messages.error(request, f"{field}: {error}")
    else:
        form = SignUpForm()
    
    return render(request, 'users/register.html', {'form': form})

@login_required
def user_profile(request):
    # 获取用户评分数据
    user_ratings = Rating.objects.filter(user=request.user)
    ratings_count = user_ratings.count()
    
    # 计算平均评分
    average_rating = 0
    if ratings_count > 0:
        average_rating = sum(r.rating for r in user_ratings) / ratings_count
    
    # 获取最常评价的类型
    genres = []
    for rating in user_ratings:
        for genre in rating.movie.genres.all():
            genres.append(genre.name)
    
    favorite_genre = "暂无数据"
    if genres:
        genre_counter = Counter(genres)
        favorite_genre = genre_counter.most_common(1)[0][0]
    
    # 获取最近评分
    recent_ratings = user_ratings.order_by('-created_at')[:5]
    
    # 为用户生成推荐
    recommendations = []
    if ratings_count > 0:
        # 从用户高评分电影中获取相似电影
        high_rated_movies = [r.movie for r in user_ratings.filter(rating__gte=4)]
        if high_rated_movies:
            for movie in high_rated_movies[:2]:  # 只用前两部高评分电影
                similar = movie.recommend_similar_movies()
                for sim_movie in similar:
                    if sim_movie not in recommendations and sim_movie.id not in [m.id for m in high_rated_movies]:
                        recommendations.append(sim_movie)
                        if len(recommendations) >= 3:
                            break
    
    context = {
        'ratings_count': ratings_count,
        'average_rating': average_rating,
        'favorite_genre': favorite_genre,
        'recent_ratings': recent_ratings,
        'recommendations': recommendations[:3]  # 最多显示3部推荐电影
    }
    return render(request, 'users/profile.html', context)

@login_required
def user_ratings(request):
    # 获取排序方式
    sort_by = request.GET.get('sort', 'date')
    
    # 获取并排序用户评分
    user_ratings = Rating.objects.filter(user=request.user)
    
    if sort_by == 'rating':
        user_ratings = user_ratings.order_by('-rating')
    elif sort_by == 'title':
        user_ratings = user_ratings.order_by('movie__title')
    else:  # 默认按日期
        user_ratings = user_ratings.order_by('-created_at')
    
    # 分页
    paginator = Paginator(user_ratings, 10)  # 每页显示10条评分
    page = request.GET.get('page')
    user_ratings = paginator.get_page(page)
    
    context = {
        'user_ratings': user_ratings,
        'sort_by': sort_by
    }
    return render(request, 'users/ratings.html', context)

@login_required
def delete_rating(request, rating_id):
    """删除用户评分的API"""
    if request.method == 'POST':
        rating = get_object_or_404(Rating, id=rating_id, user=request.user)
        rating.delete()
        return JsonResponse({'status': 'success'})
    return JsonResponse({'status': 'error'})

@login_required
def user_recommendations(request):
    # 获取推荐类型
    recommendation_type = request.GET.get('type', 'similar')
    
    # 推荐类型显示名称
    type_names = {
        'similar': '基于您喜欢的电影',
        'genre': '基于您喜欢的类型',
        'popular': '热门电影'
    }
    
    # 判断用户是否有评分
    has_ratings = Rating.objects.filter(user=request.user).exists()
    
    # 根据不同推荐类型获取推荐
    recommended_movies = []
    
    if recommendation_type == 'similar' and has_ratings:
        # 基于用户高评分电影的相似电影
        high_rated = Rating.objects.filter(user=request.user, rating__gte=4)
        if high_rated.exists():
            for rating in high_rated[:3]:  # 只取前3个高评分
                similar_movies = rating.movie.recommend_similar_movies()
                for movie in similar_movies:
                    # 避免重复和已评分的电影
                    if (movie not in recommended_movies and 
                        not Rating.objects.filter(user=request.user, movie=movie).exists()):
                        movie.recommendation_reason = f"因为您喜欢《{rating.movie.title}》"
                        recommended_movies.append(movie)
                        if len(recommended_movies) >= 8:  # 最多推荐8部
                            break
    
    elif recommendation_type == 'genre' and has_ratings:
        # 基于用户喜欢的类型
        user_genres = {}
        for rating in Rating.objects.filter(user=request.user):
            for genre in rating.movie.genres.all():
                user_genres[genre.id] = user_genres.get(genre.id, 0) + rating.rating
        
        # 按评分总和排序获取用户最喜欢的类型
        if user_genres:
            favorite_genres = [genre_id for genre_id, _ in sorted(user_genres.items(), key=lambda x: x[1], reverse=True)[:2]]
            
            # 获取这些类型的高评分电影
            for genre_id in favorite_genres:
                genre = Genre.objects.get(id=genre_id)
                genre_movies = Movie.objects.filter(genres=genre).annotate(avg_rating=Avg('rating__rating')).order_by('-avg_rating')
                
                for movie in genre_movies[:5]:  # 每个类型取前5部
                    if (movie not in recommended_movies and 
                        not Rating.objects.filter(user=request.user, movie=movie).exists()):
                        movie.recommendation_reason = f"基于您喜欢的{genre.name}类型"
                        recommended_movies.append(movie)
                        if len(recommended_movies) >= 8:
                            break
    
    # 如果前两种方法没有足够推荐或用户选择热门电影
    if len(recommended_movies) < 8 or recommendation_type == 'popular':
        # 获取最高评分电影
        popular_movies = Movie.objects.annotate(avg_rating=Avg('rating__rating'), num_ratings=Count('rating')).filter(num_ratings__gte=3).order_by('-avg_rating')[:12]
        
        for movie in popular_movies:
            if (movie not in recommended_movies and 
                not Rating.objects.filter(user=request.user, movie=movie).exists()):
                if recommendation_type == 'popular':
                    movie.recommendation_reason = "热门高评分电影"
                else:
                    movie.recommendation_reason = "您可能也会喜欢这部热门电影"
                recommended_movies.append(movie)
                if len(recommended_movies) >= 8:
                    break
    
    context = {
        'recommended_movies': recommended_movies,
        'recommendation_type': recommendation_type,
        'recommendation_type_display': type_names.get(recommendation_type, '推荐电影'),
        'has_ratings': has_ratings
    }
    return render(request, 'users/recommendations.html', context)

@login_required
def api_user_stats(request):
    """获取用户统计数据的API"""
    user_ratings = Rating.objects.filter(user=request.user)
    ratings_count = user_ratings.count()
    
    average_rating = 0
    if ratings_count > 0:
        average_rating = sum(r.rating for r in user_ratings) / ratings_count
    
    return JsonResponse({
        'ratings_count': ratings_count,
        'average_rating': f"{average_rating:.1f}"
    })

@login_required
def api_recommended_movies(request):
    """获取推荐电影的API"""
    limit = int(request.GET.get('limit', 4))
    
    # 判断用户是否有评分
    has_ratings = Rating.objects.filter(user=request.user).exists()
    recommended_movies = []
    
    if has_ratings:
        # 从用户高评分电影中获取相似电影
        high_rated = Rating.objects.filter(user=request.user, rating__gte=4)
        if high_rated.exists():
            for rating in high_rated[:2]:  # 只取前2个高评分
                similar_movies = rating.movie.recommend_similar_movies()
                for movie in similar_movies:
                    # 避免重复和已评分的电影
                    if (movie not in recommended_movies and 
                        not Rating.objects.filter(user=request.user, movie=movie).exists()):
                        recommended_movies.append(movie)
                        if len(recommended_movies) >= limit:
                            break
    
    # 如果没有足够推荐，添加热门电影
    if len(recommended_movies) < limit:
        # 获取最高评分电影
        popular_movies = Movie.objects.annotate(
            avg_rating=Avg('rating__rating'), 
            num_ratings=Count('rating')
        ).filter(num_ratings__gte=3).order_by('-avg_rating')[:limit*2]
        
        for movie in popular_movies:
            if (movie not in recommended_movies and 
                not Rating.objects.filter(user=request.user, movie=movie).exists()):
                recommended_movies.append(movie)
                if len(recommended_movies) >= limit:
                    break
    
    # 转换成JSON格式
    movies_data = []
    for movie in recommended_movies[:limit]:
        movies_data.append({
            'id': movie.id,
            'title': movie.title,
            'year': movie.year,
            'poster_url': movie.poster_url or ''
        })
    
    return JsonResponse({'movies': movies_data})

def user_login(request):
    """自定义登录视图"""
    if request.method == 'POST':
        form = AuthenticationForm(request, data=request.POST)
        if form.is_valid():
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            user = authenticate(username=username, password=password)
            if user is not None:
                login(request, user)
                messages.success(request, f"欢迎回来，{username}！")
                # 获取next参数，如果存在则重定向到该URL
                next_url = request.GET.get('next', 'home')
                return redirect(next_url)
            else:
                messages.error(request, "用户名或密码不正确！")
        else:
            messages.error(request, "登录表单无效，请检查输入！")
    else:
        form = AuthenticationForm()
    
    return render(request, 'users/login.html', {'form': form})

def user_logout(request):
    """用户登出视图"""
    logout(request)
    messages.success(request, "您已成功退出登录！")
    return redirect('home')

def login_redirect(request):
    """重定向到正确的登录页面"""
    return redirect('login')  # 'login' 是 accounts/login/ 的名称

@login_required
def ai_personalized_recommendations(request):
    """AI个性化推荐视图"""
    recommendations = ai_recommender.get_personalized_recommendations(request.user)
    return JsonResponse({'recommendations': recommendations})

def ai_mood_recommendations(request):
    """基于心情的AI推荐视图"""
    mood = request.GET.get('mood', '')
    if not mood:
        return JsonResponse({'error': '请提供心情描述'}, status=400)
    
    recommendations = ai_recommender.get_mood_based_recommendations(mood)
    return JsonResponse({'recommendations': recommendations})

def ai_movie_analysis(request, movie_id):
    """电影AI分析视图"""
    movie = get_object_or_404(Movie, id=movie_id)
    analysis = ai_recommender.analyze_movie(movie)
    return JsonResponse({'analysis': analysis})

def ai_similar_movies(request):
    """相似电影推荐视图"""
    movie_title = request.GET.get('title', '')
    if not movie_title:
        return JsonResponse({'error': '请提供电影标题'}, status=400)
    
    similar_movies = ai_recommender.get_similar_movies(movie_title)
    return JsonResponse({'similar_movies': similar_movies})

def chatbot_response(request):
    """聊天机器人响应视图"""
    if request.method != 'POST':
        return JsonResponse({'error': '只接受POST请求'}, status=405)
    
    user_message = request.POST.get('message', '')
    if not user_message:
        return JsonResponse({'error': '请提供消息内容'}, status=400)
    
    # 从会话中获取对话历史
    conversation_history = request.session.get('chat_history', [])
    
    # 获取回复
    bot_response = chatbot_service.get_response(user_message, conversation_history)
    
    # 更新对话历史
    conversation_history.append({"role": "user", "content": user_message})
    conversation_history.append({"role": "assistant", "content": bot_response})
    
    # 只保留最近的10条消息（避免会话过长）
    if len(conversation_history) > 20:
        conversation_history = conversation_history[-20:]
    
    # 更新会话
    request.session['chat_history'] = conversation_history
    
    return JsonResponse({'response': bot_response}) 